ObjcUnit 1.2

March 2002

ObjcUnit is a unit testing framework for Objective-C on Mac OS X. It's design was copied from JUnit, written by Erich Gamma and Kent Beck, and then adapted somewhat for Objective-C.

Summary of Changes between 1.1 and 1.2

When Peter did the “spike” for the expectation stuff, he went on what he remembered from the “Endo-Testing” article. He worked on his own ExpectationList class for a small project on his spare time. However, that was one class that did everything he needed. And one thing it did was to not fail if there were no expectations.

Then he decided to add the code to ObjcUnit, so he downloaded the Java framework from http://www.mockobjects.com/ and examined it for a while, then realized that their design was semantically equivalent. And since familiar is better, he created corresponding Objective-C classes, with tests, and added them to the framework. However, he forgot all about the “never fail if there are no expectations” business. So we've fixed this in 1.2.

Peter was content for a while, then he realized he was missing the one class that did everything. He didn't feel comfortable with adding lots of instance variables of various subclasses to AbstractExpectation (which, by the way was introduced in this version after some refactoring) – he wanted to be able to add one expectation object that does everything. So he created the ExpectationGroup class, which lets you do things like:

	- (void)setExpectedSetNameCalls:(int)count {
		[[expectationGroup addedCounterWithName:
			@"-setName: calls"] setExpectedCount:count];
	}

	- (void)setExpectedName:(NSString *)aName {
		[[expectationGroup addedValueWithName:
			@"name"] setExpectedObject:aName];
	}

	- (void)setName:(NSString *)aName {
		[[expectationGroup counterNamed:@"-setName: calls"]
			increment];
		[[expectationGroup valueNamed:@"name"]
			setActualObject:aName];
	}

I think this is nice. It definitely saves work. Check out the MockCoder class for an example of how it is used.

Malte found out how to get rid of the “selector not recognized” warning that was printed right in the middle of the dots when the tests are run. See the WeWantNoSelectorNotRecognizedWarnings category in TestCase.m.

Summary of Changes between 1.0 and 1.1

To celebrate the new year, we added the missing methods -assertNil: and -assert:same: (with corresponding methods for supplying messages). These prints more information when failing when a message has not been supplied – e.g. “expected nil but was ...”. The method -assertNotNil: now also prints such a message.

Then we got lazy until Malte added the constants FailuresOccurred and ErrorsOccurred, returned by TestRunnerMain upon failures and errors – that is, if there were errors, ErrorsOccurred is returned (regardless if there were failures); if there were failures, FailuresOccurred is returned; otherwise it returns 0.

Weeks passed, and then suddenly Peter began adding stuff for using “mock objects” (that is, stubs that contain test logic), more exactly the classes ExpectationSet, ExpectationList, ExpectationCounter and ExpectationValue – inspired by the framework by Tim Mackinnon, Steve Freeman and Philip Craig, available at http://www.mockobjects.com/ (there's an article there called “Endo-Testing: Unit Testing with Mock Objects” that is worth reading, although we're more of the opinion that you should keep the mocking to a minimum instead of using it as the norm).

Anyway, the Expectation* classes are there for your own mocks, as well as for mocks that will be in the framework. As of now, there's only MockCoder, which mocks NSCoder to ease testing of objects that implement the NSCoding protocol (see the Examples project for an ... eh, example). The idea is that the framework should contain a library of mocks for Apple's framework classes. Please submit mocks that you make to us!

Added a file template for Project Builder. Copy the .pbfiletemplate bundle in the Extras/ directory to /Developer/ProjectBuilder Extras/File Templates/Cocoa.

Added a +suiteWithName: method to the TestSuite class.

Added an article on how to set up a Project Builder project with a second target for the tests. Check the Documentation/ directory.

Added the constant NoFailuresOrErrorsOccurred and fixed a strangeness at the end of TestRunnerMain (stuff weren't released).

We will release both a .dmg and a .tar.gz for each new version starting now.

Summary of Changes between Beta and 1.0

The beta was released in April 2001 under the name O2Unit. First, we changed the name since we thought “O2” was a bit confusing (it is a class name prefix we use at Oops). Someone on the Wiki (http://c2.com/cgi/wiki) thought it had something to do with some OO database. Then perhaps someone might want to write a testing framework for the Oberon-2 language. So we settled for the name “ObjcUnit” (not to be confused with “OCUnit”, which is a more SUnit-style testing framework for Objective-C).

Then we dropped the “O2Unit” prefixes from all the classes. We decided to go without prefixes since the chance of name clashes should be small anyway.

The assert methods had too much Java flavor, so they have been changed. Now, you should write [self assert:obj1 equals:obj2 message:@"obj1 should be equal to obj2"]; instead of [self assertEquals:@"obj1 should be equal to obj2" :obj1 :obj2] (which we admit looks pretty stupid).

In addition, we have recreated the project and now have a tool target for running the tests. It is also better organized than before. And we added some examples.

Contents of the Release

Read Me.rtf	this file
ObjcUnit/	Project Builder project for the framework
	Tests/	the tests
	Classes/	the classes
	MockObjects/	the mock object classes
	Documentation/	documentation and articles
Examples/	Project Builder project with some examples
Extras/	additional stuff, like Project Builder file templates
Documentation/	symlink to ObjcUnit/Documentation/

Installation

1.	Open the Terminal application.
2.	Change directory to where the disk image was mounted (by typing cd and dragging and dropping the mounted disk image icon onto the Terminal window), or to where you extracted the contents of the .tar.gz file (i.e., where this file is located).
3.	Change directory to ObjcUnit/.
4.	Type pbxbuild -target ObjcUnit DSTROOT=$HOME install (or DSTROOT=/ if you want it system-wide).

To verify that the framework has been installed properly, open the Examples project and build and run it.

Getting Started

With this distribution two articles from the JUnit distribution are included. The article “Test Infected - Programmers Love Writing Tests” by Kent Beck is a good intro to using a testing framework, although the examples are in Java for JUnit. The Objective-C Money, MoneyBag and MoneyTest classes are included in the Examples project for comparison.

Acknowledgements

Thanks to Kent Beck and Erich Gamma for the JUnit framework, and to Holger Hoffstätte for code samples for enumerating all methods for an object. Thanks also to Robert Bowdidge at Apple for some sample code that we haven't incorporated into ObjcUnit yet (for displaying the call stack).

About ObjcUnit

At Oops, in the days when we weren't forced to program in Java, some of us were using OCUnit by Sen:te (http://www.sente.ch/). Along with Apple WebObjects getting Java enabled, more and more projects were Java projects and hence we started using JUnit a lot.

Then Mac OS X was pre-released and at that time, Malte Tancred was hired by a project in Stockholm. Since Malte lives in Gothenburg, he became a weekly commuter for a couple of months and lived in the cold, dark basement that is known as the Oops Stockholm HQ. One night he decided to try to get OCUnit to compile on Mac OS X, but ran into troubles. Suddenly he found himself borrowing the JUnit design and porting it to Objective-C. It only took an hour or two and apparently was a fun way to kill some time.

We had heard of people wanting a more JUnit-style testing framework for Objective-C, so we thought that it would be fun to release it. We released a beta in April 2001, but then nothing happened for a few months. We talked a lot about getting it to 1.0 status, but never got around to it. Not until December the same year we, as we say in Sweden, “grabbed ourselves by the collars” and finalized the 1.0 version.

ObjcUnit is distributed under the IBM Public License Version 1.0, since we think that we have to do this, having copied the JUnit design.

For more info, visit the ObjcUnit homepage at http://oops.se/objcunit/ or e-mail us at objcunit@oops.se.

Malte Tancred & Peter Lindberg
Computer Programmers
Oops AB, Sweden

Copyright © 2001, 2002, International Business Machines Corporation and others.
All Rights Reserved.